#include "app_readwritedid.h"
#include "app_upgrade.h"
#include "CbApInfo.h"
#include "mid_sysbackup.h"

uint8_t DIDF15BData[19];
uint8_t DIDF180Data[32] __attribute__((at(Boot_Version_Address))) = DIDF180_BootSoftwareIdentification;

uint8 *Addr70000 = (uint8 *)Fingerprint_Address;
uint8 *Addr71000 = (uint8 *)Public_Key_Address;
const uint8 writeBufPkey[386] = { 0xA9, 0x2C, 0x1A, 0xAA, 0x88, 0xBE, 0x95, 0x17, 0xE6, 0xF7, 0xF0, 0x95, 0x1A, 0x83, 0xEB, 0x58, 
								  0x86, 0x48, 0xFA, 0x02, 0x5D, 0xA0, 0xD1, 0xB5, 0x90, 0x51, 0x1F, 0x8D, 0xB4, 0x46, 0xCC, 0xCC, 
								  0xD0, 0x1C, 0x25, 0x2D, 0xF2, 0x6F, 0x9A, 0x37, 0x58, 0x32, 0xEE, 0x5A, 0x8F, 0x73, 0x4B, 0xE3, 
								  0x49, 0xF6, 0xFA, 0x8B, 0x25, 0xB2, 0x25, 0xBF, 0xE9, 0x18, 0x80, 0xF9, 0x89, 0xAF, 0xB7, 0xCA, 
								  0x1E, 0xDD, 0xEC, 0x08, 0x46, 0x91, 0x58, 0xB9, 0x5F, 0x1E, 0xE1, 0x28, 0xF3, 0x04, 0x1C, 0x37, 
								  0xC1, 0xA1, 0x85, 0x5C, 0xF5, 0xD5, 0xEB, 0xD8, 0x53, 0x1E, 0x5D, 0xE4, 0x40, 0xB7, 0xAE, 0xD0, 
								  0x4C, 0x30, 0x18, 0x6C, 0x1D, 0xF1, 0xF2, 0x60, 0x41, 0x47, 0xBB, 0x23, 0x28, 0xD8, 0xA5, 0x9C, 
								  0xB6, 0x61, 0xBF, 0x60, 0x8C, 0x24, 0x2A, 0x20, 0x0E, 0x8C, 0x05, 0x07, 0xC8, 0xC4, 0x94, 0x5A, 
								  0xF5, 0x5E, 0xB2, 0x2F, 0xDE, 0x92, 0xAE, 0xDA, 0x53, 0x53, 0xD8, 0x48, 0x1B, 0x21, 0x54, 0x04, 
								  0xAD, 0x62, 0x92, 0x22, 0xC5, 0xBD, 0xA0, 0x82, 0x0F, 0x9F, 0x0F, 0xEA, 0x00, 0xAE, 0x2A, 0xEA, 
								  0x7A, 0x82, 0x5D, 0xB2, 0x10, 0xCE, 0x07, 0xBA, 0xCC, 0x39, 0x30, 0x36, 0x1A, 0x2D, 0xD5, 0xAF, 
								  0xE3, 0x7C, 0x4C, 0x5E, 0x75, 0xFC, 0xFD, 0x94, 0x1C, 0xC0, 0x5D, 0xE2, 0x66, 0x98, 0x9A, 0xBF, 
								  0xB1, 0x60, 0xE4, 0xA0, 0xDF, 0x39, 0xC3, 0xCB, 0x23, 0x10, 0x40, 0xD9, 0x8E, 0x0C, 0x0F, 0x1F, 
								  0xA0, 0x0E, 0x78, 0xAD, 0xEA, 0x4F, 0xA6, 0xF7, 0x7A, 0x05, 0x9C, 0x95, 0x32, 0x68, 0xCB, 0x3D, 
								  0xF1, 0xD9, 0x06, 0x52, 0x4D, 0xB0, 0x09, 0xE2, 0xAF, 0x0E, 0x1E, 0xB2, 0x92, 0x64, 0x2A, 0x34, 
								  0xB3, 0x34, 0xB0, 0xDC, 0xBF, 0xD5, 0x8E, 0x60, 0x9E, 0x19, 0xE9, 0x59, 0x1E, 0x22, 0x85, 0x66, 
								  0xFE, 0xA4, 0xF5, 0x65, 0x04, 0x75, 0x21, 0x42, 0xD7, 0x4C, 0xDA, 0xC9, 0x11, 0xF9, 0xE8, 0xF6, 
								  0xAF, 0xFC, 0x85, 0x76, 0xD8, 0x24, 0x4C, 0x8B, 0x9D, 0x28, 0x51, 0x88, 0x33, 0xEB, 0x49, 0x43, 
								  0xA4, 0xD0, 0x97, 0xE1, 0xD2, 0x2F, 0x80, 0x65, 0x18, 0x9F, 0xDD, 0xE2, 0xB0, 0xFC, 0x45, 0x8A, 
								  0xE9, 0x00, 0x36, 0xF1, 0xC3, 0x11, 0x55, 0x81, 0x78, 0xAF, 0xAC, 0x6F, 0x52, 0xB9, 0xEF, 0x9A, 
								  0x78, 0x62, 0x7D, 0xC4, 0x7E, 0x0B, 0xD7, 0x10, 0x0E, 0x75, 0x1F, 0xEA, 0xA1, 0x63, 0x32, 0x2F, 
								  0x08, 0x8C, 0x7B, 0x0B, 0xF5, 0x3D, 0x34, 0xE1, 0x5A, 0x3E, 0xC2, 0xAD, 0xC4, 0x64, 0x56, 0xA8, 
								  0x84, 0x2A, 0xD7, 0xD3, 0xB5, 0x74, 0xF4, 0xBD, 0xD8, 0x5C, 0x8D, 0x38, 0xF6, 0xBA, 0xE5, 0xE9, 
								  0x17, 0xEF, 0xAD, 0x4C, 0x4E, 0xCD, 0x44, 0x08, 0xE2, 0x3A, 0xDE, 0x7D, 0x4A, 0xD1, 0xB6, 0x5F, 
								  0x26, 0xF5};
extern uint8 key_m[];
extern uint8 key_e[];

uint8 PubkeyTmp[400] = { 0 };
uint8 pubkeyStatus;
void PubkeyInit(void)
{
   uint16 i;
   uint8 *m = Addr71000;

   pubkeyStatus = m[0];
   if (pubkeyStatus <= 2 ) //00h:Not written, 01h:Written, default value, 02h:Written, Non-default value
   {
      for (i = 0; i < 384; i++) {
         key_m[i] = m[i+1];
      }
      key_e[0] = m[1 + i++];
      key_e[1] = m[1 + i++];
   }
   else
   {
      pubkeyStatus = 1;
   }
}

void app_readdid_init(void)
{
	uint16 i;
	uint8 *m = Addr71000;
	if (*Addr70000 == 0xFF) {  //init Fingerprint
		DIDF15BData[0] = 0x18;
		DIDF15BData[1] = 0x04;
		DIDF15BData[2] = 0x17;
		for (i = 3; i < 19; i++) {
         DIDF15BData[i] = '0' + i - 3;
      }
	  upgrade_flash_write_direc(Fingerprint_Address, (uint8_t *)&DIDF15BData[0], 19);
	}
	else
	{
		memcpy(DIDF15BData, m, 19);
	}
	PubkeyInit();

	// memcpy((uint8*)&DIDF180Data[0], DIDF180_BootSoftwareIdentification, 32);
}
// read write DID
Std_ReturnType DIDF180_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF180_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF180_BootSoftwareIdentification, 32);

    return ret;
}

Std_ReturnType DIDF184_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

Std_ReturnType DIDF184_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	for(int i = 0; i < 19; i++)
	{
		*data++ = *(uint8_t *)(Fingerprint_Address + i);
	}
    return ret;
}

Std_ReturnType DIDF184_WriteConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF184_WriteCbk(uint8 *data, uint16 dataLength, Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
	memcpy((uint8_t *)&DIDF15BData[0], data, dataLength);
	upgrade_flash_write_direc(Fingerprint_Address, (uint8_t *)&DIDF15BData[0], 19);
	*errorCode = DCM_E_POSITIVERESPONSE;
	ret = E_OK;
	return ret;
}


Std_ReturnType DIDF187_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

#define DIDF187_VehicleManufacturerSparePartNumberDataIdentifier				                "601001962AA     "
Std_ReturnType DIDF187_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF187_VehicleManufacturerSparePartNumberDataIdentifier, 16);
    return ret;
}

Std_ReturnType DIDF089_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

#define DIDF089_VehicleManufacturerECUHardwareVersionNumberDataIdentifier				        "0.0.1                   "
Std_ReturnType DIDF089_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF089_VehicleManufacturerECUHardwareVersionNumberDataIdentifier, 24);
    return ret;
}

Std_ReturnType DIDF013_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

#define DIDF013_VehicleManufacturerLogisticSoftwarePartNumberDataIdentifier				        "S00000193720    "
Std_ReturnType DIDF013_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF013_VehicleManufacturerLogisticSoftwarePartNumberDataIdentifier, 16);
    return ret;
}

Std_ReturnType DIDF18A_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

#define DIDF18A_SystemSupplierIdentifier 						"4TT       " 
Std_ReturnType DIDF18A_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF18A_SystemSupplierIdentifier, 10);
    return ret;
}

Std_ReturnType DIDF0F3_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

Std_ReturnType DIDF0F3_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	*data++ = 0;
	*data++ = 0;
	*data++ = 0;
	*data++ = 0;
	return ret;
}
/*
Std_ReturnType DIDF15B_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF15B_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF15BData, 15);
    return ret;
}
Std_ReturnType DIDF020_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF020_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
    //todo
    *data++ = pubkeyStatus;
    return ret;
}
Std_ReturnType DIDF021_WriteConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF021_WriteCbk(uint8 *data, uint16 dataLength, Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
	uint16 i =0;
	uint8 offset = 1;
	if(pubkeyStatus != 0){
		*errorCode = DCM_E_CONDITIONSNOTCORRECT;
			return ret;
	}
	pubkeyStatus = 1; //00h:Not written, 01h:Written, default value, 02h:Written, Non-default value  
	for(i = 0; i < 386; i++) 
	{
		if(writeBufPkey[i] != data[i]) //"memcmp" cannot be used, because the stack overflows
		{
			pubkeyStatus = 2;
			break;
		}
	}  
	PubkeyTmp[0] = pubkeyStatus;

	for (i = 0; i < 386; i++) {
		PubkeyTmp[i+offset] = data[i];
	}
	for (i = 0; i < 384; i++) {
		key_m[i] = PubkeyTmp[i+offset];
	}
	key_e[0] = PubkeyTmp[offset + i++];
	key_e[1] = PubkeyTmp[offset + i++];
	upgrade_flash_write_direc(Public_Key_Address, (uint8_t *)&PubkeyTmp[0], sizeof(PubkeyTmp));
	
	*errorCode = DCM_E_POSITIVERESPONSE;
	ret = E_OK;
	return ret;
}
Std_ReturnType DIDF022_WriteConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}

Std_ReturnType DIDF022_WriteCbk(uint8 *data, uint16 dataLength, Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
	uint16 i =0;
	for(i = 0; i < 384; i++) 
	{
		if(key_m[i] != data[i]) //"memcmp" cannot be used, because the stack overflows
		{
			*errorCode = DCM_E_CONDITIONSNOTCORRECT;
			return ret;
		}
	}
	pubkeyStatus = 0; //00h:Not written, 01h:Written, default value, 02h:Written, Non-default value
	PubkeyTmp[0] = pubkeyStatus;
	memcpy((uint8*)&PubkeyTmp[1],data,386);
	upgrade_flash_write_direc(Public_Key_Address, (uint8_t *)&PubkeyTmp[0], sizeof(PubkeyTmp));
	*errorCode = DCM_E_POSITIVERESPONSE;
	ret = E_OK;
	return ret;
}
Std_ReturnType DIDF187_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF187_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF187_VehicleManufacturerSparePartNumberDataIdentifier, 16);
    return ret;
}
Std_ReturnType DIDF191_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF191_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF191_VehicleManufacturerECUHardwareNumber, 5);
    return ret;
}
Std_ReturnType DIDF18A_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
#define DIDF18A_SystemSupplierIdentifier 						"4TT" 
Std_ReturnType DIDF18A_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF18A_SystemSupplierIdentifier, 3);
    return ret;
}
Std_ReturnType DIDF180_ReadConditionCheckCbk(Dcm_NegativeResponseCodeType *errorCode)
{
	Std_ReturnType ret = E_OK;
    //todo
    *errorCode = DCM_E_POSITIVERESPONSE;
    return ret;
}
Std_ReturnType DIDF180_ReadCbk(uint8 *data)
{
	Std_ReturnType ret = E_OK;
	memcpy(data, DIDF180_BootSoftwareIdentification, 32);

    return ret;
}
*/
